#pragma once

///Class managing an OpenGL texture.
class								Texture
{
	public:
		///Create a new Texture object.
		///@param aWidth Width of the texture, in pixels.
		///@param aHeight Height of the Texture, in pixels.
									Texture					(uint32_t aWidth, uint32_t aHeight);

		///Destroy a Texture object.
									~Texture				();
		
		///Fill the Texture with a solid color.
		///@param aColor RGBA Color used to fill the texture.
		void						Clear					(uint32_t aColor);

		///Map the Texture's pixel buffer into memory.
		///@return A pointer to the Texture's memory.
		uint32_t*					Map						();

		///Unmap the Texture from memory. Must be called an equal amount of times as Map to fully unmap the Texture.
		void						Unmap					();
	
		///Get the width of the Texture.
		///@return The width of the Texture, in pixels.
		uint32_t					GetWidth				() const {return Width;};

		///Get the height of the Texture.
		///@return The height of the Texture, in pixels.
		uint32_t					GetHeight				() const {return Height;};

		///Get the pitch of the Texture.
		///@return The height of the Texture, in pixels not bytes.
		uint32_t					GetPitch				() const {return Pitch;};

		///Enable or disable bi-linear filtering for the Texture.
		///@param aOn New state of the Texture filter.
		void						SetFilter				(bool aOn) {Filter = aOn;}

		///Unused
		///@return 0
		uint32_t					GetFlags				() const {return 0;};

		///Get the shift for the Red component of a texel.
		///@param The shift for the Red component of a texel.
		uint32_t					GetRedShift				() const {return 16;};

		///Get the shift for the Green component of a texel.
		///@param The shift for the Green component of a texel.
		uint32_t					GetGreenShift			() const {return 8;};

		///Get the shift for the Blue component of a texel.
		///@param The shift for the Blue component of a texel.
		uint32_t					GetBlueShift			() const {return 0;};

		///Get the shift for the Alpha component of a texel.
		///@param The shift for the Alpha component of a texel.
		uint32_t					GetAlphaShift			() const {return 24;};
		
		///Pack a set of values into a valid texel.
		///@param aRed The red component.
		///@param aGreen The green component.
		///@param aBlue The blue component.
		///@param aAlpha The alpha component.
		///@return A Texel.
		uint32_t					ConvertPixel			(uint8_t aRed, uint8_t aGreen, uint8_t aBlue, uint8_t aAlpha) const {return (aRed << GetRedShift()) | (aBlue << GetBlueShift()) | (aGreen << GetGreenShift()) | (aAlpha << GetAlphaShift());}

	public: //Helper, do not call directly
		///Apply the Texture as the active OpenGL texture.
		void						Apply					();

		///Get the OpenGL texture ID for this Texture.
		///@return The ID of the texture, generated by glGenTextures.
		uint32_t					GetID					() const {return ID;}

	private:
		uint32_t					BufferID;				///The Texture's OpenGL pixel buffer ID.
		uint32_t					ID;						///The Texture's OpenGL texture ID.
		uint32_t					MapCount;				///The number of times the texture has been mapped.
		uint32_t*					Pixels;					///A pointer to the Texture's pixel data if mapped, null otherwise.

		uint32_t					Width;					///The width of the Texture in pixels.
		uint32_t					Height;					///The height of the Texture in pixels.
		uint32_t					Pitch;					///The pitch of the Texture in pixels.
		bool						Filter;					///Determine if the texture uses bi-linear filtering.
		bool						Valid;					///False if the texture needs its pixels re-uploaded when applied.
};


